Benutzerdefinierte CR-Funktionen verwenden
Eine Datei für eine benutzerdefinierte CR-Funktion muss über eine bestimmte Schnittstelle verfügen, um von Visum identifiziert zu werden. Am wichtigsten ist es, dass jede Datei *.dll die aufgelisteten Funktionen exportiert, damit Visum diese Datei *.dll während der Umlegung korrekt aufrufen kann.
Datei *.dll für eine benutzerdefinierte CR-Funktion vorbereiten
Zu Visum gibt es eine Header-Datei UserDefinedVDF.h, die Sie direkt nutzen können, um die erforderlichen Funktionen in C++ zu implementieren. Die Header-Datei und ein vollständiges Beispielprojekt für Microsoft Visual Studio befinden sich im Verzeichnis ...\Programme\PTV Vision\PTV Visum 2024\Data\UserDefVDF. Prinzipiell können Sie jede Programmiersprache nutzen, solange damit eine Windows-dll erstellt werden kann, die über eine Schnittstelle entsprechend der Funktionsdeklarationen von C++ verfügt.
Die Funktionen müssen genau die Signatur wie in UserDefinedVDF.h haben. Sie dürfen weder den Rückgabewert ändern noch Parameter entfernen oder vertauschen.
Hinweis: Die CR-Funktion muss stetig und monoton steigend hinsichtlich der Belastungen sein. Dies gilt für alle möglichen Werte der Parameter. |
Obligatorische Funktionen in der *.dll
Deklaration |
char Init (); |
Beschreibung |
Diese Funktion wird von Visum einmal direkt nach dem Start und vor dem ersten Nutzen anderer Funktionen aufgerufen. Hinweis Nutzen Sie die Funktion, um die eigenen Datenstrukturen zurückzusetzen oder gegebenenfalls andere vorbereitende Funktionen durchzuführen. |
Parameter |
keine |
Rückgabewert |
true – Zurücksetzen erfolgreich false – Zurücksetzen nicht erfolgreich, die Datei *.dll sollte nicht aufgerufen werden |
Deklaration |
void Destroy (); |
Beschreibung |
Diese Funktion wird von Visum einmal direkt vor dem Schließen und nach dem letzten Aufruf der anderen Funktionen aufgerufen. Hinweis Nutzen Sie die Funktion gegebenenfalls für Aufräumoperationen, zum Beispiel, um dynamisch angeforderten Speicher freizugeben. |
Parameter |
keine |
Rückgabewert |
keiner |
Deklaration |
char IsThreadSafe(); |
Beschreibung |
Diese Funktion wird von Visum einmal direkt nach dem Start und vor dem ersten Aufruf anderer Funktionen aufgerufen. Der Rückgabewert gibt an, ob die unten angeführten Calc...-Funktionen simultan benutzbar implementiert sind. Die Funktion kann dann ein weiteres Mal aufgerufen werden, ehe der vorige Aufruf beendet ist. Hinweis Dieser Parallelismus kann bei einer Multithread-Implementierung der Umlegungsverfahren von Visum genutzt werden. |
Parameter |
keine |
Rückgabewert |
true – simultan benutzbar false – nicht simultan benutzbar |
Deklaration |
char DependsOnTSys (); |
Beschreibung |
Diese Funktion wird von Visum einmal direkt nach dem Start und vor dem ersten Aufruf anderer Funktionen aufgerufen. Wenden Sie die Funktion an, um anzuzeigen, ob die eigene Funktion unterschiedliche Fahrzeiten je Verkehrssystem liefert oder ob Belastungen je Verkehrssystem benötigt werden. Ist das nicht der Fall, dann kann Visum auf das Extrahieren und Weiterleiten dieser Belastungen zu den Calc...-Funktionen verzichten und muss die Funktion nicht für jedes Verkehrssystem aufrufen, was Rechenzeit spart. Falls die Funktion für Anbindungen verwendet wird, muss der Wert 1 zurückgeliefert werden (siehe Rückgabewert). Für (Ober-)Abbiegebeziehungen und (Ober-)Knoten muss der Wert 0 zurückgeliefert werden (siehe Rückgabewert). |
Parameter |
keine |
Rückgabewert |
2 – benötigt Belastungen je Verkehrssystem, liefert aber für alle Verkehrssysteme dasselbe Ergebnis 1 – benötigt Belastungen je Verkehrssystem und liefert potentiell für unterschiedliche Verkehrssysteme ein unterschiedliches Ergebnis 0 – nutzt nur Gesamtbelastung in PkwE und liefert für alle Verkehrssysteme dasselbe Ergebnis |
Deklaration |
const wchar_t * GetName (const char * langid); |
Beschreibung |
Liefert einen lesbaren Namen für die Funktion, der als Eintrag in den Auswahllisten für CR-Funktionen erscheint. |
Parameter |
langid ist ein Sprachcode, der genutzt werden kann, um den Namen optional in andere Sprachen zu übersetzen. Derzeit sind folgende Werte möglich. ‘ENG’ – Englisch ‘DEU’ – Deutsch ‘FRA’ – Französisch ‘ITA’ – Italienisch ‘POL’ – Polnisch ‘ESP’ – Spanisch ‘CHI’ – Chinesisch ‘JAP’ – Japanisch Hinweise Sie können die Funktion vernachlässigen, wenn sie nicht erforderlich ist. Wird der Sprachcode genutzt, sollte immer der Fall eines unbekannten Codes behandelt werden, da eventuell zukünftig weitere Sprachen ohne ausdrückliche Benachrichtigung hinzugefügt werden. |
Rückgabewert |
Der lesbare Name der Funktion als 16-bit UTF-8 Zeichenstring. Der Wert muss als UTF-8 zurückgegeben werden, um die Sonderzeichen einiger Sprachen – vor allem asiatischer – aufzunehmen. Visum erwartet einen Pointer auf einen String, der in der Datei *.dll gespeichert ist. Hinweis Der String darf nicht auf dem Stack alloziert werden, damit die Adresse nach Abschluss des Funktionsaufrufs noch gültig ist. |
Deklaration |
const char * GetID (); |
Beschreibung |
Sollte einen String liefern, der als eindeutige ID für die Funktion genutzt wird. Diese ID wird intern in der Versionsdatei gespeichert, um Ihre getroffene Zuordnung zu Anbindungen oder Typen von Strecken, Knoten oder Abbiegern zu erfassen, und als ID der Funktion im Format *.xml für die Verfahrensparameter. |
Parameter |
keine |
Rückgabewert |
Der ID-String als ASCII-String. Der String darf nur die Zeichen 0..9, a..z, A..Z enthalten. Visum erwartet einen Pointer auf einen String, der in der Datei *.dll gespeichert ist. Hinweis Der String darf nicht auf dem Stack alloziert werden, damit die Adresse nach Abschluss des Funktionsaufrufs noch gültig ist. |
Deklaration |
int GetInterfaceVersion(); |
Beschreibung |
Die Definition der Schnittstelle für Dateien vom Typ *.dll ist versioniert, damit Funktionsdeklarationen später verändert oder erweitert werden können. Geben Sie die Versionsnummer der Header-Datei zurück, für die Sie Ihre Funktionen programmieren. Visum vergleicht die gelieferte Nummer mit den dem Programm bekannten Versionsnummern, ruft die dll-Funktionen entsprechend auf oder gibt eine Fehlermeldung aus, wenn die Schnittstellenversion nicht unterstützt wird. |
Parameter |
keine |
Rückgabewert |
die Versionsnummer |
Deklaration |
void SetTsysInfo (int numtsys, const wchar_t * tsysids[]) |
Beschreibung |
Visum ruft diese Funktion jedes Mal auf, wenn sich die Menge der IV-Verkehrssysteme ändert. Als Parameter werden die Anzahl der Verkehrssysteme und ein Array mit den Codes je Verkehrssystem übergeben. Aus Effizienzgründen übergibt Visum an die Calc…-Funktionen das Verkehrssystem als numerischen Index, und zwar als 0-basierten Index in das Feld tsysids. Hinweis Um teure Stringvergleiche in diesen oft aufgerufenen Funktionen zu vermeiden, sollten Sie den numerischen Index der Verkehrssysteme, die in den CR-Funktionen speziell behandelt werden müssen, in SetTsysInfo einmal auswerten und speichern. |
Parameter |
numtsys – die Anzahl der Verkehrssysteme (= Länge des Feldes tsysids) tsysids – Feld von 16-bit UTF-8 Zeichen-Strings, wovon jedes Feld dem Wert des Attributs Code für eines der in der Umlegung genutzten Verkehrssysteme entspricht. |
Rückgabewert |
nein |
Deklaration |
double Calc (int tsysind, bool tsysisopen, int typ, int numlanes, double length, double cap, double v0, double t0, double gradient, double pcuvol, double vehvolsys[], int uval1, int uval2, int uval3, int uvaltsys, double para_a, double para_b, double para_c, double para_d, double para_f, double para_a2, double para_b2, double para_d2, double para_f2, double satcrit) |
Beschreibung |
Die Implementierung der CR-Funktion selbst. Visum ruft diese Funktion auf, um die aktuelle Fahrzeit tAkt je Strecke, Abbieger, Anbindung, Knoten und ein Verkehrssystem zu berechnen. Hinweis Achten Sie darauf, dass die Funktion in recheneffizienter Form codiert ist, da sie sehr oft aufgerufen wird. |
Parameter |
Für die Netzobjekte werden diverse Parameter übergeben. Hinweis Einzelheiten finden Sie in der nachfolgenden Tabelle. |
Rückgabewert |
tAkt in [s] |
In Abhängigkeit vom Netzobjekttyp übergibt Visum folgende Parameter an die Funktion Calc.
|
Strecke |
Anbindung |
Abbieger |
Knoten |
int tsysind |
0-basierter Index des Verkehrssystems (bezogen auf das Feld tsysids, das in SetTsysInfo übergeben wurde), für das tAkt berechnet werden soll |
|||
bool tsysisopen |
Ist das Netz für das Verkehrssystem geöffnet |
|||
int typ |
0..99 |
0..9 |
0..9 |
0..99 |
int numlanes |
AnzFahrstreifen |
1 (willkürlich) |
1 (willkürlich) |
1 (willkürlich) |
double length |
Länge [kurze Länge] |
Länge [kurze Länge] |
0 (willkürlich) |
0 (willkürlich) |
double cap |
KapIV [PkwE] |
10E10 oder KapIV [PkwE], wenn Anbindungsanteile verwendet werden, die sich auf den Gesamt-Quell-/Zielverkehr beziehen. |
KapIV [PkwE] |
KapIV [PkwE] |
double v0 |
v0 [m/s] |
Länge/t0 (oder 0, wenn t0=0) |
0 |
0 |
double t0 |
Länge/v0 [s] (oder 10E10, wenn v0=0) |
t0 [s] |
||
double gradient |
Steigung |
0 (willkürlich) |
0 (willkürlich) |
0 (willkürlich) |
double pcuvol |
BelPkwE in [PkwE] als Linearkombination aller VSys-Belastungen in [Fzg] multipliziert mit dem Wert des Attributs PkwE für das Verkehrssystem. Hinweis Ist bei den meisten Anwendungen empfohlen. |
|||
double vehvolsys[] |
Alternativ – für nicht-standardisierte PkwE-Berechnungen – ein Array aller VSys-Belastungen in [Fzg]. Die Reihenfolge der Einträge entspricht der Reihenfolge im Feld tsysids, das an SetTsysInfo übergeben wird. |
|||
double uval1/2/3 |
die Werte der Attribute ZWert1, ZWert2 und ZWert3 |
|||
double uvaltsys |
Wert des Attributs ZWert-VSys je VSys |
0 |
||
double para_a..f2 |
aus dem Fenster Parameter für CR-Funktion |
|||
double satcrit |
aus dem Fenster Parameter für CR-Funktion (CR-Funktionen auswählen und Parameter einstellen) |
Optionale Funktionen in der *.dll
Deklaration |
double CalcDerivative (int tsysind, bool tsysisopen, int typ, int numlanes, double length, double cap, double v0, double t0, double gradient, double pcuvol, double vehvolsys[], int uval1, int uval2, int uval3, int uvaltsys, double para_a, double para_b, double para_c, double para_d, double para_f, double para_a2, double para_b2, double para_d2, double para_f2, double satcrit) |
Beschreibung |
Diese Funktion wird vom Programm aufgerufen, um für ein bestimmtes VSys und je Strecke, Abbieger, Anbindung, Knoten die Ableitung der aktuellen Fahrzeit tAkt hinsichtlich der Auslastung zu berechnen. Diese Funktion wird nur innerhalb der bikriteriellen Maut-Umlegungsmethoden TRIBUT-Gleichgewichtsumlegung und TRIBUT-Lernverfahren aufgerufen. Hinweise Achten Sie darauf, dass die Funktion in recheneffizienter Form codiert ist, da sie sehr oft aufgerufen wird. Ist die Funktion nicht in der *.dll implementiert, dann berechnet Visum die Ableitung numerisch, was jedoch länger dauert als das Bereitstellen von CalcDerivative() in der *.dll. |
Parameter |
genau wie für Calc() |
Rückgabewert |
Ableitung von tAkt in [s] |
Deklaration |
double CalcIntegral (int tsysind, bool tsysisopen, int typ, int numlanes, double length, double cap, double v0, double t0, double gradient, double pcuvol, double vehvolsys[], int uval1, int uval2, int uval3, int uvaltsys, double para_a, double para_b, double para_c, double para_d, double para_f, double para_a2, double para_b2, double para_d2, double para_f2, double satcrit) |
Beschreibung |
Diese Funktion wird vom Programm aufgerufen, um für ein bestimmtes VSys und je Strecke, Abbieger, Anbindung, Knoten das Integral der aktuellen Fahrzeit tAkt hinsichtlich der Auslastung zu berechnen. Hinweis Diese Funktion wird nicht mehr benötigt und muss daher nicht implementiert werden. Ist die Funktion nicht in der *.dll implementiert, dann berechnet Visum das Integral numerisch, was jedoch länger dauert als das Bereitstellen von CalcDerivative() in der *.dll. |
Parameter |
genau wie für Calc() |
Rückgabewert |
Integral von 0 bis Auslastung der CR-Funktion in [s] |
Alternative Schnittstelle mit Angabe statischer Attribute in der *.dll
Die Funktion Calc wird mit einer Anzahl netzobjektabhängiger Attribute wie Typ, Anzahl Fahrstreifen usw. aufgerufen, aber damit ist kein Zugriff auf weitere Attribute wie z.B. benutzerdefinierte Attribute möglich. Für diesen Fall können in der *.dll drei weitere, optionale Funktionen implementiert werden, durch die der Zugriff auf beliebige numerische Attribute des Netzobjekts möglich ist. Diese Attribute müssen innerhalb einer Umlegung statisch sein, d.h. sie dürfen nicht von der Belastung abhängen. Ein Zugriff auf belastungsabhängige Attribute führt zu falschen Werten. Wenn die folgenden drei Funktionen implementiert sind, wird die alternative Schnittstelle verwendet. Die Funktionen Calc(), CalcDerivative() und CalcIntegral() sollten in diesem Fall nicht implementiert werden.
Deklaration |
int GetNumStaticAttributes() |
Beschreibung |
Diese Funktion liefert die Anzahl der statischen Attribute zurück, für die Werte an CalculateWithStaticAttributes() übergeben werden. |
Parameter |
keine |
Rückgabewert |
Anzahl der statischen Attribute |
Deklaration |
const wchar_t * GetStaticAttributeID(int attributesIndexZeroBased) |
Beschreibung |
Sollte einen String liefern, der eine gültige AttributID enthält. |
Parameter |
Der Index des Attributs (0 bis GetNumStaticAttributes()-1) |
Rückgabewert |
Der AttributID-String als ASCII-String. Visum erwartet einen Pointer auf einen String, der in der Datei *.dll gespeichert ist. Hinweis Der String darf nicht auf dem Stack alloziert werden, damit die Adresse nach Abschluss des Funktionsaufrufs noch gültig ist. |
Deklaration |
double CalculateWithStaticAttributes(int tsysind, char tsysisopen, double cap, double t0, pcuvol, double basevol, double vehvolsys[], double staticAttributeValues[], double para_a, double para_b, double para_c, double para_d, double para_f, double para_a2, double para_b2, double para_d2, double para_f2, double satcrit) |
Beschreibung |
Die Implementierung der CR-Funktion selbst. Visum ruft diese Funktion auf, um die aktuelle Fahrzeit tAkt je Strecke, Abbieger, Anbindung, Knoten und ein Verkehrssystem zu berechnen. Hinweis Achten Sie darauf, dass die Funktion in recheneffizienter Form codiert ist, da sie sehr oft aufgerufen wird. |
Parameter |
Für die Netzobjekte werden diverse Parameter übergeben. Die Parameter entsprechen denen der Funktion Calc(), es fehlen allerdings typ, numlanes, length, v0, uval1, uval2, uval3, uvaltsys. Stattdessen wird in staticAttributeValues ein Array der Länge GetNumStaticAttributes() übergeben mit den durch GetStaticAttributeID() spezifizierten Werten. Falls ein Attribut nicht existiert oder das Attribut nicht numerisch ist, wird 0 übergeben. |
Rückgabewert |
tAkt in [s] |
Beispiel für eine benutzerdefinierte CR-Funktion
Zwei Verkehrssysteme – PKW und LKW – werden in der Umlegung verwendet.
- Für PKW (Car) hat die CR-Funktion eine lineare Form, wobei die Steigung bei satcrit wechselt.
- Für LKW (HGV) werden zwei Steigungswechsel bei d und e verwendet.
Dabei gilt Folgendes.
Die Ableitungen sind folgende:
Quellcode der Datei *.dll
#include “UserDefinedVDF.h” #include “tchar.h” int indHGV; // index of the HGV tsys wchar_t VDFName[] = _T(“ManualExample”); // UTF-8 !! char VDFID[] = “MANEX”; int INTERFACE_VERSION = 1; boolchar Init() { indHGV = -1; return true; } void Destroy() { } char DependsOnTSys() { return 1; }
const wchar_t* GetName(const char *langid)
{
return VDFName;
}
const char* GetID(const char *langid)
{
return VDFID;
}
int GetInterfaceVersion()
{
return INTERFACE_VERSION;
}
void SetTsysInfo (int numtsys, const wchar_t * tsysids[])
{
for (int i = 0; i < numtsys; i++)
{
if (_tcscmp(tsysids[i], _T(“HGV”)) == 0) indHGV = i;
}
}
double Calc (int tsysind, bool tsysisopen, int typ, int numlanes, double length, double cap, double v0, double t0, double gradient, double pcuvol, double vehvolsys[], int uval1, int uval2, int uval3, int uvaltsys, double para_a, double para_b, double para_c, double para_d, double para_f, double para_a2, double para_b2, double para_d2, double para_f2, double satcrit)
{
double sat = pcuvol / cap;
if (tsysind != indHGV) {
if (sat < satcrit)
return t0 * (1 + para_a * sat);
else
return t0 * (1 + para_a * satcrit + para_b * (sat-satcrit));
}
else {
if (sat < d)
return t0 * (1 + para_a2 * sat);
else {
if (d <= sat && sat < e)
return t0 * (1 + para_a2 * d + para_b2 * (sat-d));
else
return t0 * (1 + para_a2 * d + para_b2*(e-d) + para_c*(sat-e));
}
}
}
double CalcDerivative (int tsysind, bool tsysisopen, int typ, int numlanes, double length, double cap, double v0, double t0, double gradient, double pcuvol, double vehvolsys[], int uval1, int uval2, int uval3, int uvaltsys, double para_a, double para_b, double para_c, double para_d, double para_f, double para_a2, double para_b2, double para_d2, double para_f2, double satcrit)
{
double sat = pcuvol / cap;
if (tsysind != indHGV) {
if (sat < satcrit)
return para_a;
else
return para_b;
}
else {
if (sat < d)
return para_a2;
else {
if (d <= sat && sat < e)
return para_b2;
else
return para_c;
}
}
}
Beispiel für eine benutzerdefinierte CR-Funktion mit statischen Attributen
Die Implementierung einer BPR-Funktion, um den Zugriff auf statische Attribute zu zeigen.
Quellcode der Datei *.dll
#include "UserDefinedVDF.h"
#include "tchar.h"
#include <math.h>
#include <float.h>
wchar_t VDFName[] = _T("ExampleStaticAttributes");
char VDFID[] = "PTV_EXAMPLESTATICATTRIBUTES";
int INTERFACE_VERSION = 1;
char Init()
{
return true;
}
enum MyStaticIDs
{
V0PrT,
Length,
CapPrT,
TypeNo,
LastId
};
static const int MyMaxIDLength = 100;
static wchar_t staticAttributeIDs[LastId][MyMaxIDLength] =
{
L"V0PRT",
L"LENGTH",
L"CAPPRT",
L"TYPENO"
};
int GetNumStaticAttributes()
{
return LastId;
}
const wchar_t * GetStaticAttributeID(int attributesIndexZeroBased)
{
return staticAttributeIDs[attributesIndexZeroBased];
}
void Destroy()
{
}
char IsThreadSafe()
{
return true;
}
char DependsOnTSys()
{
return 0;
}
const wchar_t* GetName(const char *langid)
{
return VDFName;
}
const char* GetID()
{
return VDFID;
}
int GetInterfaceVersion()
{
return INTERFACE_VERSION;
}
void SetTsysInfo (int numtsys, const wchar_t * tsysids[])
{
}
double CalculateWithStaticAttributes(int tsysind, char tsysisopen, double cap, double t0,
double pcuvol, double basevol, double vehvolsys[],
double staticAttributeValues[],
double para_a, double para_b, double para_c, double para_d, double para_f,
double para_a2, double para_b2, double para_d2, double para_f2, double satcrit)
{
double const v0PrT = staticAttributeValues[V0PrT];
double const length = staticAttributeValues[Length];
double const mycap = staticAttributeValues[CapPrT];
double const typeNo = staticAttributeValues[TypeNo];
if (cap <= 0 || para_c <= 0 || v0PrT <= 0 || typeNo < 0) {
return DBL_MAX;
}
double sat = pcuvol / (cap * para_c);
double myt0 = 3.6 * length / v0PrT;
return myt0 * (1 + para_a * (pow(sat, para_b)));
}
Benutzerdefinierte CR-Funktionen importieren
1. Übersetzen und linken Sie die *.dll mit der gewünschten Entwicklungsumgebung.
2. Benennen Sie die Bibliothekdatei in der Form VisumVDF***.dll.
Hinweise: Dabei können Sie *** durch jeden String ersetzten, der mit den Konventionen für Windows-Dateinamen vereinbar ist. Achten Sie darauf, dass die durch Funktion GetID() produzierten IDs eindeutig sind. Haben mehrere Dateien *.dll die gleiche ID, so wird nur die erste in Visum geladen. Alle weiteren werden ignoriert. |
3. Legen Sie die Datei in das Verzeichnis ...\Benutzer\<Benutzer>\AppData\Roaming\PTV Vision\PTV Visum 2024\UserVDF-DLLs.
Hinweise: Dieses Verzeichnis wird bei der Installation standardmäßig angelegt und beim Programmstart durchsucht. Alternativ können Sie ein anderes Verzeichnis als Standardverzeichnis für Ihre angelegten Dateien *.dll definieren. Der entsprechende Pfad muss dazu in die Standardpfaddatei std.pfd gespeichert werden (Speicherort von Dateien ändern). Diese Änderung ist erst nach einem Neustart des Programms wirksam. Wenn Sie das Projektverzeichnis für benutzerdefinierte CR-Funktionen ändern, werden die enthaltenen Dateien *.dll zuätzlich geladen und die existierenden bleiben erhalten. |
Beim Programmstart sucht Visum nach Dateien *.dll und lädt die Inhalte. Dabei werden nur Dateien geladen, deren Windows-Edition (32 oder 64 Bit) der verwendeten Visum-Edition entsprechen. Die benutzerdefinierten CR-Funktionen stehen dann gemeinsam mit den vordefinierten CR-Funktionen im Fenster Parameter für CR-Funktion zur Verfügung.
Hinweise: Nach dem Programmstart sucht Visum nicht mehr nach neuen Dateien *.dll. Wenn Sie eine neue benutzerdefinierte CR-Funktion hinzufügen, müssen Sie Visum erneut starten. Wenn Sie eine Datei *.bmp mit dem gleichen Dateinamen wie die Datei *.dll in das gleiche Verzeichnis speichern, wird das Bild der gewählten CR-Funktion im Fenster Parameter für CR-Funktion angezeigt. |
Benutzerdefinierte CR-Funktionen mit VisualStudio C++ erstellen
Im Installationsverzeichnis von Visum im Unterordner Data\UserDefVDF finden Sie eine Beispielumgebung für Visual Studio 2019.
Hinweis: Vor der Verwendung sollten Sie den Inhalt von Data\UserDefVDF in einen eigenen Ordner außerhalb von C:\Programme kopieren, denn bei einem Update von Visum kann dieser Ordner überschrieben werden. |
Sowohl die Debug- als auch die Release-Konfiguration erstellen *.dll-Dateien, die mit Visum kompatibel sind. Die Release-Variante ist jedoch zur Laufzeit schneller.
- ► Starten Sie Visual Studio 2019 und öffnen Sie die Solutiondatei UserDefVDF.sln.
Um eine eigene *.dll zu erstellen, können Sie entweder eines der bestehenden Projekte ändern oder ein neues Projekt zur Solution hinzufügen.